home *** CD-ROM | disk | FTP | other *** search
/ MacAddict 117 / MacAddict 117.dmg / Software / Utilities / Tidy Up 1.0.9 (shareware).dmg / Tidy Up! / Tidy Up!.app / Contents / Resources / iPodDBRead.pl < prev    next >
Encoding:
Perl Script  |  2006-02-09  |  4.3 KB  |  189 lines

  1. #!/usr/bin/perl
  2. #
  3. #  Copyright (C)2004 Giuseppe Giunto
  4. #  Reads data from iPodDB
  5. #  URL: http://www.hyperbolicsoftware.com/
  6. #
  7. #  Uses code from tunes2html.pl
  8. #  Copyright (C) 2003-2004 Joe Mallon <jmmallon at joescafe dot com>
  9. #  URL: http://www.joescafe.com/tunes2html
  10. #
  11. # iTunes, and iPod are registered trademarks of Apple Computer, Inc.
  12. #
  13. # This product is not supported/written/published by Apple!
  14. #
  15.  
  16. sub get_nod_a($);
  17.  
  18. $itdbPath = @ARGV[0];
  19. $iTunesVers = @ARGV[1];
  20.  
  21. $ipodmagic = "6d 68 62 64 68 00 00 00";
  22.  
  23. open(FILE, $itdbPath) or die "Can't open input file: $!\n";    
  24.  
  25. #check the header
  26. if(getfoo(0, (length($ipodmagic)+2)/3) ne $ipodmagic) {
  27.     die "err: could open $file, but:\nI don't think, thats an ipod - tunes db!\n";
  28. }
  29.  
  30. $qq = 292; #the magic number!! (the HARDCODED start of the first mhit)
  31.  
  32. # gnutunes header
  33. while($qq != -1) {
  34.     %info = ();
  35.     ($qq,$stuffptr) = get_nod_a($qq); #get_nod_a returns wher it's guessing the next MHIT, if it fails, it returns '-1'
  36.         
  37.     if (defined(%$stuffptr)) {
  38.         %info = %$stuffptr;
  39.         
  40.         $artist = $info{'artist'};
  41.         $path = $info{'path'};
  42.         $year = (defined($info{'year'})) ? $info{'year'} : "";
  43.         $song = $info{'song'};
  44.         $album = ($info{'album'}) ? $info{'album'} : "";
  45.         $track = (defined($info{'track'})) ? $info{'track'} : 0;
  46.         $size = $info{'size'};
  47.         $id = $info{'id'};
  48.         
  49.         print $song."*_*".$artist."*_*".$album."*_*".$year."*_*".$track."*_*".$size."*_*".$path."*_*".$id."#_#";
  50.     }
  51. }
  52.             
  53. close(FILE);
  54.             
  55. sub get_nod_a($)
  56. {
  57.     my(@jerk, $sum, $zip, $otxt, $oid);
  58.     my %stuff = ();
  59.     ($sum) = @_;
  60.     if(getfoo($sum, 4) eq "6d 68 69 74") { #aren't we lost? 
  61.         
  62.         $stuff{'id'} = getshoe($sum+16 , 4);
  63.         $stuff{'size'}  = getshoe($sum+36 , 4);
  64.         $stuff{'length'} = int(getshoe($sum+40,4)/1000);
  65.         $stuff{'track'} = getshoe($sum+44,4); #song number
  66.         $stuff{'year'} = getshoe($sum+52,4); #year
  67.             
  68.         $sum += ($iTunesVers > 46) ? 244 : 156;            #1st mhod starts here!
  69.         while($zip != -1) {
  70.             $sum = $zip+$sum; 
  71.             ($zip, $oid, $otxt) = get_mhod($sum);    #returns the number where its guessing the next mhod, -1 if it's failed
  72.             $jerk[$oid] = xmlstring($otxt);
  73.         }
  74.         
  75.         $stuff{'song'} = $jerk[1];
  76.         $stuff{'path'} = $jerk[2];
  77.         $stuff{'album'} = $jerk[3];
  78.         $stuff{'artist'} = $jerk[4];
  79. #        $stuff{'sortart'} = $jerk[12];
  80.         
  81.         return ($sum-$zip-1,\%stuff);          #black magic
  82.     } else {
  83.         return "-1";
  84.     }
  85. }
  86.  
  87. #get a SINGLE mhod entry:
  88. #
  89. # get_mhod(START_OF_MHOD);
  90. #
  91. # return+seek = new_mhod should be there
  92. sub get_mhod()
  93. {
  94.     my($seek, $xl, $ml, $mty, $foo, $id);
  95.     ($seek) = @_;
  96.     
  97.     $id = getfoo($seek, 4);           #are we lost?
  98.         
  99.     $ml = getshoe($seek+8, 4);
  100.     $mty = getshoe($seek+12, 4);         #genre number
  101.     $xl = getshoe($seek+28,4);           #Entrylength
  102.             
  103.     if($id ne "6d 68 6f 64") { #is the id INcorrect??
  104.         $ml = -1; 
  105.     } else {
  106. #get the TYPE of the DB-Entry
  107.         $foo = getstr($seek+40, $xl); #string of the entry
  108.         $foo =~ tr/\0//d; #we have many \0.. killem!
  109.             
  110.         return ($ml, $mty, $foo);
  111.     }
  112. }
  113.  
  114. sub getfoo {
  115. #reads $anz chars from FILE and returns HEX values!
  116.     my($anz, $buffer, $xx, $xr, $start, $noseek);
  117.     ($start, $anz, $noseek) = @_;
  118. # paranoia checks
  119.     if(!$start) { $start = 0; }
  120.     if(!$anz) { $anz = "1"; }
  121.     
  122. #seek to the given position
  123.     
  124.     seek(FILE, $start, 0);
  125. #start reading
  126.     read(FILE, $buffer, $anz);
  127.     foreach(split(//, $buffer)) {
  128.       $xx = sprintf("%02x ", ord($_));
  129.       $xr = "$xr$xx";
  130.     }
  131.     chop($xr);# no whitespace at end
  132.  
  133.     return $xr;
  134. }
  135.  
  136. sub getshoe
  137. {
  138. #reads $anz chars from FILE and returns int 
  139.     my($anz, $buffer, $xx, $xr, $start, $noseek, $xxt);
  140.     ($start, $anz, $noseek) = @_;
  141.     
  142. # paranoia checks
  143.     if(!$start) { $start = 0; }
  144.     if(!$anz) { $anz = "1"; }
  145.     
  146. #seek to the given position    
  147.     seek(FILE, $start, 0);
  148.     
  149. #start reading
  150.     read(FILE, $buffer, $anz);
  151.     foreach(split(//, $buffer)) {
  152.         $xx = sprintf("%02X", ord($_));
  153.         $xr = "$xx$xr";
  154.     }
  155.     $xr = oct("0x".$xr);
  156.     return $xr;
  157. }
  158.  
  159. sub getstr
  160. {
  161. #reads $anz chars from FILE and returns a string!
  162.     my($anz, $buffer, $xx, $xr, $start, $noseek);
  163.     ($start, $anz, $noseek) = @_;
  164. # paranoia checks
  165.     if(!$start) { $start = 0; }
  166.     if(!$anz) { $anz = "1"; }
  167.     
  168. #seek to the given position
  169. #if 3th ARG isn't defined
  170.     
  171.     seek(FILE, $start, 0);
  172. #start reading
  173.     read(FILE, $buffer, $anz);
  174.     
  175.     return $buffer;
  176. }
  177.  
  178. sub xmlstring
  179. {
  180.     my($ret) = @_;
  181.     $ret =~ s/&/&/g;
  182.     $ret =~ s/"/"/g;
  183.     $ret =~ s/</</g;
  184.     $ret =~ s/>/>/g;
  185.     $ret =~ s/'/'/g;
  186.     return $ret;
  187. }
  188.  
  189.